#include "binary_constraint.h"

namespace fcsp {
using namespace std;

BinaryConstraint::BinaryConstraint(Variable *x, Variable *y): x_(x), y_(y) {
  x->AddAdjacent(*y);
  y->AddAdjacent(*x);
}

BinaryConstraint::BinaryConstraint(Variable *x, Variable *y, 
    map< int, map<int, double> > preferences): x_(x), y_(y) {
  x->AddAdjacent(*y);
  y->AddAdjacent(*x);
  preferences_.insert(preferences.begin(), preferences.end());
}

void BinaryConstraint::Destroy() const {
  x().RemoveAdjacent(y());
  y().RemoveAdjacent(x());
}

void BinaryConstraint::AddPreference(int value_x, int value_y, double pref) {
  preferences_[value_x][value_y] = pref;
}

bool BinaryConstraint::SetPreference(int value_x, int value_y, double pref) {
  if (x().IsValue(value_x) && y().IsValue(value_y)) {
    preferences_[value_x][value_y] = pref;
    return true;
  }
  return false;
}

double BinaryConstraint::GetPreference(int value_x, int value_y) const {
  double preference = 0.0;
  if (x().IsValue(value_x) && y().IsValue(value_y)) {
    preference = (preferences_.at(value_x)).at(value_y);
  }
  return preference;
}

pair<map<int, double> &, bool> BinaryConstraint::GetPreferences(int value_x) {
  map< int, map<int, double> >::iterator it;
  it = preferences_.find(value_x);
  bool res = it != preferences_.end();
  map<int, double> &prefs = (*it).second;

  return pair<map<int, double> &, bool>(prefs, res);
}

bool BinaryConstraint::RemovePreference(int value_x, int value_y) {
  if (x().IsValue(value_x) && y().IsValue(value_y)) {
    preferences_.erase(value_x);
    return true;
  }
  return false;
}

bool BinaryConstraint::IsValue(int value_x, int value_y) {
  return x().IsValue(value_x) && y().IsValue(value_y);
}
} // namespace fcsp
